<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    var data = [
      {
        id: 1,
        name: '家电',
        goods: [
          {
            id: 11,
            name: '冰箱'
          },
          {
            id: 12,
            name: '洗衣机'
          }
        ]
      },
      {
        id: 2,
        name: '服饰'
      }
    ]

    // 要求就是输入id,可以出现对应的商品

    function getId (json, id) {
      json.forEach(function (item) {
        if (item.id == id) {
          // console.log(item);
          // 注意这里是判断可以再次进行递归的条件
          // 就是满足已定义的条件，有资格进行递归，才调用它
        } else if (item.goods && item.goods.length > 0) {
          getId(item.goods, id)
        }
      })
    }
    getId(data, 1)
    getId(data, 2)
    getId(data, 11)
    getId(data, 12)

    // 加上返回值的写法
    // 内部可以获取，但是返回的时候，就变成了nudefined未定义
    // 后来发现是因为，递归调用的时候，这个let 出来的name就被覆盖掉了，内部重新定义了一个name
    // 然后你在这个函数的外部想要获取它，肯定就不可能了
    let name
    const getids = (json, id) => {
      // let name 在函数内部声明，会出现作用域的问题
      json.forEach(item => {
        if (item.id === id) {
          name = item.name
        } else if (item.goods && item.goods.length > 0) {
          getids(item.goods, id)
        }
      })
      return name
    }

    // console.log(getids(data, 12));

    // 或者可以这样类优化，外部再套一层函数,来控制作用域
    // 这个写法就是闭包，_getid2就是getid2的私有方法，外部无法调用
    const getid2 = (json, id) => {
      let name
      function _getid2 (json, id) {
        // let name 在函数内部声明，会出现作用域的问题
        json.forEach(item => {
          if (item.id === id) {
            name = item.name
            // console.log(name);
          } else if (item.goods && item.goods.length > 0) {
            _getid2(item.goods, id)
          }
        })
        return name
      }
      return _getid2(json, id)
    }
    // _getid2(data, 11)  // 外部是无法访问的报错：_getid2 is not defined
    console.log(getid2(data, 11));
  </script>
</body>

</html>